﻿using System;
using System.Collections.Generic;
using System.Text;

using XRpgLibrary.ScriptClasses;
using XRpgLibrary.CharacterClasses;
using XRpgLibrary.WorldClasses;
using XRpgLibrary.FadeClasses;

using Microsoft.Xna.Framework;

namespace XRpgLibrary.Scripts.Global
{
    public class PortalToPoint : GameScript
    {
        private Vector2 destination;
        private string levelName;
        private string layerName;
        private bool fadeOutComplete = false;
        private bool teleported = false;
        private float fadeTime;

        private Character moveCharacter;
        private World world;

        public PortalToPoint(float x = 640f, float y = 640f, float fadeTime = .25f, string levelName = "", string layerName = "")
        {
            this.destination = new Vector2(x, y);
            this.levelName = levelName;
            this.layerName = layerName;
            this.fadeTime = fadeTime;
        }

        public override void Execute(Character self, object trigger, ScriptContext context, GameTime gameTime)
        {
            if (!string.IsNullOrEmpty(levelName) && string.IsNullOrEmpty(layerName))
                throw new Exception("If you do not specify a destination level or layer name, the portal must be on the same level and layer as the character.");

            if (!string.IsNullOrEmpty(levelName) && context.World.CurrentLevel.MapName != levelName)
                context.World.MoveToLevel((Character)trigger, levelName, layerName);

            if (moveCharacter == null)
                moveCharacter = (Character)trigger;

            if (world == null)
                world = context.World;

            if (base.Self == null)
                base.Self = self;

            if (world.Fader == null)
                world.Fader = new FadeClasses.Fade(context.Game, Color.Black);

            if (ActionQueue(FadeOut, Teleport, FadeIn))
            {
                world.Fader = null;
                fadeOutComplete = false;
                teleported = false;
                moveCharacter = null;
            }
        }

        private object[] FadeOut(object[] args)
        {
            if (!moveCharacter.IsPlayer || fadeOutComplete || world.Fader.Visibility == VisibilityState.Visible)
            {
                fadeOutComplete = true;
                return new object[0];
            }

            if (world.Fader.Visibility == VisibilityState.Invisible)
                world.Fader.FadeToColor(fadeTime);

            return null;
        }

        private object[] FadeIn(object[] args)
        {
            if (!moveCharacter.IsPlayer || world.Fader.Visibility == VisibilityState.Invisible)
                return new object[0];

            if (world.Fader.Visibility == VisibilityState.Visible)
                world.Fader.FadeFromColor(fadeTime);

            return null;
        }

        private object[] Teleport(object[] args)
        {
            if (!teleported)
            {
                world.CurrentLevel.MoveCharacterTo(moveCharacter, destination);
                teleported = true;
            }
            return new object[0];
        }


    }
}
